package dao

import (
	"gorm.io/gorm"
	"gotham-plan-manage/internal/infra/database/mysql/plan/po"
	"gotham-plan-manage/pkg/consts"
)

/*
   @author:zhongyang
   @date:2023/4/3
   @description:计划表数据库操作
*/

type PlanDao struct {
}

func NewPlanDao() *PlanDao {
	return &PlanDao{}
}

func (p *PlanDao) Create(db *gorm.DB, planPO *po.PlanPO) error {
	return db.Create(&planPO).Error
}

func (p *PlanDao) Delete(db *gorm.DB, planPO *po.PlanPO) error {
	return db.Delete(&planPO).Error
}

func (p *PlanDao) GetOne(db *gorm.DB, planId string) (*po.PlanPO, error) {
	var res *po.PlanPO
	err := db.Where("plan_id = ?", planId).First(&res).Error
	if err != nil {
		return nil, err
	}
	return res, nil
}

func (p *PlanDao) Save(db *gorm.DB, planPO *po.PlanPO) error {
	return db.Updates(&planPO).Error
}

func (p *PlanDao) FindChildrenPlanListByParentId(db *gorm.DB, parentId string, userID string) ([]*po.PlanPO, error) {
	var res []*po.PlanPO
	err := db.Model(&po.PlanPO{}).Where("user_id = ? and parent_id = ?", userID, parentId).Find(&res).Error
	if err != nil {
		return nil, err
	}
	return res, nil
}

func (p *PlanDao) FindParentPlanListPage(db *gorm.DB, page int, pageSize int, userId string) ([]*po.PlanPO, int64, error) {
	var total int64
	limit := pageSize
	offset := pageSize * (page - 1)
	// 筛选所有的父计划
	db = db.Model(&po.PlanPO{}).Where("user_id = ? and parent_id = ?", userId, consts.DefaultPlanID)
	err := db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	var res []*po.PlanPO
	err = db.Limit(limit).Offset(offset).Order("finish_date asc").Find(&res).Error
	return res, total, nil
}

func (p *PlanDao) IsFinishAllTasks(db *gorm.DB, planID string) (bool, error) {
	var total int64
	err := db.Model(&po.TaskItemPO{}).Where("plan_id = ? and finish_date = ?", planID, consts.DefaultDate).Count(&total).Error
	if err != nil {
		return false, err
	}
	// 还存在未完成的任务，说明未完成所有任务
	return total == 0, nil
}

func (p *PlanDao) FindOngoingPlanIds(db *gorm.DB, userId string) ([]string, error) {
	var planIds []string
	err := db.Model(&po.PlanPO{}).Select("plan_id").Where("user_id = ? and finish_date = ?", userId, consts.DefaultDate).Find(&planIds).Error
	if err != nil {
		return nil, err
	}
	return planIds, nil
}

func (p *PlanDao) Finish(db *gorm.DB, planPO *po.PlanPO) error {
	return db.Model(&planPO).Where("plan_id = ?", planPO.PlanId).Update("finish_date", planPO.FinishDate).Error
}

func (p *PlanDao) FindAllByUserId(db *gorm.DB, userId string) ([]*po.PlanPO, error) {
	var res []*po.PlanPO
	err := db.Where("user_id = ?", userId).Find(&res).Error
	if err != nil {
		return nil, err
	}
	return res, nil
}

func (p *PlanDao) GetOngoingOneByUserId(db *gorm.DB, userId string) (*po.PlanPO, error) {
	var res *po.PlanPO
	err := db.Where("user_id = ? and finish_date = ?", userId, consts.DefaultDate).Limit(1).Find(&res).Error
	if err != nil {
		return nil, err
	}
	return res, nil
}
